iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
Modern Web

職缺資訊平台—Jobscanner系列 第 10

[前置作業] 建立 Firestore

  • 分享至 

  • xImage
  •  

*以 Client 端操作為例

建立 Firestore Database

  1. 進入 Firebase console,新建專案
  2. 側邊欄選擇「Firesotre Database」,點擊 「Create database
  3. 先選擇測試模式 (允許所有人可以讀取以及寫入資料)
  4. 選擇 database 地區

基本操作

安裝

npm install firebase

Firestore 初始化,建立 Firestore 的參照

// Initialize Firestore through Firebase
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseApp = initializeApp({
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
  projectId: '### CLOUD FIRESTORE PROJECT ID ###'
});

// Initialize Cloud Firestore and get a reference to the service
const db = getFirestore();

document 的使用

利用 setDoc(),建立一個新的 document 或是覆蓋掉既有的 document。
*doc() 會回傳 document 實體參照,即 document 在 Firestore 中的 location

setDoc(reference, data, options?)

reference: document 的參照
data: document 的內容
options: 寫入的方式 merge / mergeFields

import { doc, setDoc } from "firebase/firestore";

// 將 document "sing street" 加到 collection "movies" 中
await setDoc(doc(db, "movies", "sing street"), {
  name: "Sing Street",
  date: "2016"
});

如果不確定 document 是否存在,可傳入 merge 參數,會將新資料加到 document 中,避免整個 document 被覆蓋

import { doc, setDoc } from "firebase/firestore";

const movieRef = doc(db, 'movies', 'sing street');
setDoc(movieRef, { director: "John Carney" }, { merge: true });

利用 setDoc() 指定 ID,建立一個 document

import { doc, setDoc } from "firebase/firestore";

await setDoc(doc(db, "movies", "new-movie-id"), data);

使用 addDoc() ,自動產生 document ID 的方式建立 document

import { collection, addDoc } from "firebase/firestore";

// Add a new document with a generated id.
const docRef = await addDoc(collection(db, "movies"), {
  name: "Perfetti sconosciuti",
  date: "2016"
});
console.log("Document written with ID: ", docRef.id);

利用 updateDoc() 更新 document

import { doc, updateDoc } from "firebase/firestore";

const docRef = doc(db, "movies", "movie-id");

// 更新 'sing street' 這個 document 裡的 "director"
await updateDoc(docRef, {
  director: "John Carney"
});

serverTimestamp() 增加時間戳記紀錄

import { updateDoc, serverTimestamp } from "firebase/firestore";

const docRef = doc(db, 'movies', 'movie-id');

const updateTimestamp = await updateDoc(docRef, {
    timestamp: serverTimestamp()
});

刪除 document deleteDoc()

import { doc, deleteDoc } from "firebase/firestore";

await deleteDoc(doc(db, "movies", "movie-id"));

刪除特定的資料欄位 deleteField()

import { doc, updateDoc, deleteField } from "firebase/firestore";

const docRef = doc(db, 'movies', 'movie-id');

// 刪除 document 中的 date 欄位
await updateDoc(docRef, {
    date: deleteField()
});

使用 getDoc() 讀取 document (傳入 document 的參照位置)

import { doc, getDoc } from "firebase/firestore";

const docRef = doc(db, "movies", "Barbie");
const docSnap = await getDoc(docRef);

if (docSnap.exists()) {
  console.log("Document data:", docSnap.data());
} else {
  // docSnap.data() will be undefined in this case
  console.log("No such document!");
}

使用 where 讀取 collection 中特定的 document

import { collection, query, where, getDocs } from "firebase/firestore";

const q = query(collection(db, "movies"), where("date", "==", 2016));

const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
  console.log(doc.id, " => ", doc.data());
});

取得 collection 全部的 document

import { collection, getDocs } from "firebase/firestore";

const querySnapshot = await getDocs(collection(db, "movies"));
querySnapshot.forEach((doc) => {
  console.log(doc.id, " => ", doc.data());
});

範例 - 新增電影

建立 firebase.js,用來儲存 Firebase 設定以及取得 database 參照

// src/firebase.js
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
  apiKey: "xxxxx",
  authDomain: "xxxxx",
  projectId: "xxxxx",
  storageBucket: "xxxxx",
  messagingSenderId: "xxxxx",
  appId: "xxxxx",
};

const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);

Movie.js 用來新增電影以及顯示所有電影項目 (即 Todo List 的功能)

  1. 在 input 輸入電影名稱,點擊送出,可新增一個 document 至 movies collection 中
  2. 電影清單會顯示movies 中所有 document 的電影名稱
// src/Movie.js
import React, { useState, useEffect } from 'react';
import { db } from './firebase';
import { collection, addDoc, getDocs, serverTimestamp } from "firebase/firestore";

const Movie = () => {
    const [movie, setMovie] = useState("");
    const [movies, setMovies] = useState([]);

    const addMovie = async (e) => {
        e.preventDefault();
        try {
            const docRef = await addDoc(collection(db, "movies"), {
              name: movie,
              timestamp: serverTimestamp()
            });
            console.log("Document written with ID: ", docRef.id);
          } catch (e) {
            console.error("Error adding document: ", e);
          }
    }

    const fetchMovie = async () => {
      const querySnapshot = await getDocs(collection(db, "movies"));
      const newData = querySnapshot.docs.map((doc) => ({id: doc.id, name: doc.data().name}));
      setMovies(newData);
    }

    useEffect(()=>{
      fetchMovie();
    }, [])

    return (
        <section>
          <div>
            <h2>新增電影</h2>
              <div>
                  <input
                      type="text"
                      placeholder="電影名稱"
                      onChange={(e)=>setMovie(e.target.value)}
                  />
              </div>

              <div>
                  <button
                      onClick={addMovie}
                  >
                      送出
                  </button>
              </div>
          </div>
          <div>
            <h2> 電影清單 </h2>
            <ul>
              {movies.map(item => (<li key={item.id}>{item.name}</li>))}
            </ul>
          </div>
        </section>
    )
}

export default Movie;

*Firebase Console 查看 Firestore 資料
https://ithelp.ithome.com.tw/upload/images/20230925/20128122kcxlRfDXOZ.png


參考資料

Cloud Firestore - 官方文件
Firebase - API Reference


上一篇
[前置作業] Firestore ?
下一篇
[前置作業] Firestore 實作- 從 Cloud Functions 更新資料
系列文
職缺資訊平台—Jobscanner31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言